<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #canvas {
            border: 1px solid #ff0000;
        }
    </style>
</head>
<body>

    <canvas id="canvas" width="600" height="400"></canvas>

    <script>
        function LineChart (ctx) {
            this.ctx = ctx || document.querySelector("#canvas").getContext("2d");
            this.canvasWidth = this.ctx.canvas.width;//画布的宽
            this.canvasHeight = this.ctx.canvas.height;//高
            this.girdSize = 20;//网格大小
            this.space = 20;//原点及两轴末端距离画布边缘的大小
            this.x0 = this.space;
            this.y0 = this.canvasHeight - this.space;
            this.arrowSize = 10;//箭头的大小,箭头三角形底边10，高10
            this.dottedSize = 6;//点的尺寸大小
            this.lineColor = "#AAA";
        }

        //2、行为方法
        //初始化：
        LineChart.prototype.init = function (data) {
            this.drawGrid();
            this.drawAxis();
            this.drawDotted(data);
        }
        //绘制网格
        LineChart.prototype.drawGrid = function () {
            //横线(X轴线)
            var xLineTotal = Math.floor(this.canvasHeight / this.girdSize);
            for (let i = 0; i <= xLineTotal; i++) {
                this.ctx.beginPath();
                this.ctx.moveTo(0, i * this.girdSize + 0.5);
                this.ctx.lineTo(this.canvasWidth, i * this.girdSize + 0.5);
                this.ctx.strokeStyle = this.lineColor;
                this.ctx.stroke();              
            }
            //竖线(Y轴)
            var yLineTotal = Math.floor(this.canvasWidth / this.girdSize);
            for (let i = 0; i <= yLineTotal; i++) {
                this.ctx.beginPath();
                this.ctx.moveTo(i * this.girdSize + 0.5, 0);
                this.ctx.lineTo(i * this.girdSize + 0.5, this.canvasHeight);
                this.ctx.strokeStyle = this.lineColor;
                this.ctx.stroke();  
            }
        }
        //绘制坐标轴
        LineChart.prototype.drawAxis = function () {
            //X轴
            this.ctx.beginPath();
            this.ctx.moveTo(this.x0, this.y0);
            this.ctx.lineTo(this.canvasWidth - this.space, this.y0);
            this.ctx.lineTo(this.canvasWidth - this.space - this.arrowSize, this.y0 + this.arrowSize / 2);
            this.ctx.lineTo(this.canvasWidth - this.space - this.arrowSize, this.y0 - this.arrowSize / 2);
            this.ctx.lineTo(this.canvasWidth - this.space, this.y0);
            this.ctx.strokeStyle = "#000";
            this.ctx.stroke();
            this.ctx.fill();
            //Y轴
            this.ctx.beginPath();
            this.ctx.moveTo(this.x0, this.y0);
            this.ctx.lineTo(this.x0, this.space);
            this.ctx.lineTo(this.x0 - this.arrowSize / 2, this.space + this.arrowSize);
            this.ctx.lineTo(this.x0 + this.arrowSize / 2, this.space + this.arrowSize);
            this.ctx.lineTo(this.x0, this.space);
            this.ctx.strokeStyle = "#000";
            this.ctx.stroke();
            this.ctx.fill();
        }
        //绘制所有的点
        LineChart.prototype.drawDotted = function (data) {
            //需要先转换坐标数据成 canvas坐标
            //canvas的x轴 = canvas原点X值 + 原始坐标X值
            //canvas的y轴 = canvas原点y值 - 原始坐标y值
            var prevCanvasX; //记录上一次点的坐标
            var prevCanvasY;
            data.forEach((ele,i) => {
                //得到canvas坐标点
                let canvasX = this.x0 + ele.x;
                let canvasY = this.y0 - ele.y;

                //画点(围绕坐标点画一个长度为 this.dottedSize 的正方形)
                this.ctx.beginPath();
                this.ctx.moveTo(canvasX - this.dottedSize / 2, canvasY - this.dottedSize / 2);
                this.ctx.lineTo(canvasX + this.dottedSize / 2, canvasY - this.dottedSize / 2);
                this.ctx.lineTo(canvasX + this.dottedSize / 2, canvasY + this.dottedSize / 2);
                this.ctx.lineTo(canvasX - this.dottedSize / 2, canvasY + this.dottedSize / 2);
                this.ctx.fill();
                // this.ctx.stroke();

                if (i != 0) {
                    this.ctx.beginPath();
                    this.ctx.moveTo(prevCanvasX, prevCanvasY);
                    this.ctx.lineTo(canvasX, canvasY);
                    this.ctx.stroke();
                }
                //记录本次点的坐标，下一次循环要用到
                prevCanvasX = canvasX;
                prevCanvasY = canvasY;


            });
        }

        //坐标数据,
        var data = [
            {x:100,y:120},
            {x:200,y:180},
            {x:300,y:250},
            {x:400,y:300},
            {x:500,y:80},
        ];
        var lineChart =  new LineChart();
        lineChart.init(data);



    </script>
</body>
</html>